﻿using System;
using Microsoft.SPOT;
using System.Collections;

namespace ntools.Tools
{
    public class Xml
    {
        public static XmlElement ParseXML(string xml)
        {
            return ParseElement(ref xml);
        }

        private static XmlElement ParseElement(ref string xml)
        {
            int bodyStart = xml.IndexOf('>') + 1;
            string startElement = xml.Substring(0, bodyStart);

            XmlElement ele = new XmlElement();
            ele.Name = ExtractElementName(startElement);

            if (xml.ToCharArray()[bodyStart - 2] == '/')
            {
                ele.Value = null;
                xml = xml.Substring(bodyStart);

                return ele;
            }

            string endElement = "</" + CleanStartElement(startElement).Substring(1);

            int bodyEnd = xml.IndexOf(endElement);


            string body = xml.Substring(bodyStart, bodyEnd - bodyStart);

            if (body.ToCharArray()[0] == '<')
            {
                XmlElement first = ParseElement(ref body);

                if (body.Length == 0)
                {
                    ele.Value = first;
                }
                else
                {
                    ArrayList list = new ArrayList();

                    list.Add(first);

                    while (body.Length > 0)
                        list.Add(ParseElement(ref body));

                    ele.Value = list;
                }
            }
            else
            {
                ele.Value = body;
            }


            xml = xml.Substring(bodyEnd + endElement.Length);

            return ele;

        }

        private static string CleanStartElement(string xml)
        {
            int index = xml.IndexOf(' ');

            if (index != -1)
            {
                xml = xml.Substring(0, index) + ">";
            }

            return xml;
        }

        private static string ExtractElementName(string xml)
        {
            xml = xml.Trim('<').Trim('>').Trim('/');

            int spaceIndex = xml.IndexOf(' ');

            if (spaceIndex != -1)
                xml = xml.Substring(0, spaceIndex);

            int colonIndex = xml.IndexOf(':');

            if (colonIndex != -1)
                xml = xml.Substring(colonIndex + 1);

            return xml;
        }

        public class XmlElement
        {
            public string Name { get; set; }
            public object Value { get; set; }
            public string XML { get; set; }

            public string AsString
            {
                get
                {
                    return this.Value as string;
                }
            }

            public int AsInt
            {
                get
                {
                    return Convert.ToInt32(this.AsString);
                }
            }

            public bool AsBoolean
            {
                get
                {
                    return (string)this.Value == "True";
                }
            }

            public ArrayList AsList
            {
                get
                {
                    ArrayList list = this.Value as ArrayList;

                    if (list != null || this.Value == null)
                        return list;

                    return new ArrayList { this.Value };
                }
            }

            public string GetString(string name)
            {
                return this.GetChild(name).AsString;
            }

            public int GetInt(string name)
            {
                return this.GetChild(name).AsInt;
            }

            public bool GetBoolean(string name)
            {
                return this.GetChild(name).AsBoolean;
            }

            public ArrayList GetList(string name)
            {
                return this.GetChild(name).AsList;
            }

            public XmlElement GetChild(string name)
            {
                if (this.AsList == null)
                    return null;

                var enumerator = this.AsList.GetEnumerator();


                while (enumerator.MoveNext())
                {
                    XmlElement current = enumerator.Current as XmlElement;

                    if (current.Name == name)
                        return current;
                }

                return null;
            }

            public override string ToString()
            {
                return this.Name;
            }
        }
    }   
}
